#include "MyI2C.h"

//I2C0初始化
//无参
//无返回值
void MyI2C_0_init(void)
{
	//开始I2C使用的GPIO时钟
	rcu_periph_clock_enable(MyI2C_0_RCU_GPIOX);
	
	//设置I2C SDA引脚 的电气属性 上拉输出
	gpio_mode_set(MyI2C_0_GPIOX,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,MyI2C_0_SDA);
	//设置I2C SDA引脚 的输出配置 开漏输出 50Mhz
	gpio_output_options_set(MyI2C_0_GPIOX,GPIO_OTYPE_OD,GPIO_OSPEED_50MHZ,MyI2C_0_SDA);
	
	//设置I2C SCL引脚 的电气属性 上拉输出
	gpio_mode_set(MyI2C_0_GPIOX,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,MyI2C_0_SCL);
	//设置I2C SCL引脚 的输出配置 开漏输出 50Mhz
	gpio_output_options_set(MyI2C_0_GPIOX,GPIO_OTYPE_OD,GPIO_OSPEED_50MHZ,MyI2C_0_SCL);
	
}

//I2C协议起始信号
//在SCL高电平时，将SDA拉低
//无参
//无返回值
void MyI2C_Start(void)
{
	//确保起始时两线均为高电平
	MyI2C_0_SCL_Ctrl(1);
	//等待I2C电平变更
	MyI2C_delay();
	//确保起始时两线均为高电平
	MyI2C_0_SDA_Ctrl(1);
	//等待I2C电平变更
	MyI2C_delay();
	
	//拉低SDA
	MyI2C_0_SDA_Ctrl(0);
	//等待I2C电平变更
	MyI2C_delay();
	//拉低SCL
	MyI2C_0_SCL_Ctrl(0);
	//等待I2C电平变更
	MyI2C_delay();
}

//I2C协议停止信号
//在SCL高电平时，将SDA拉高
//无参
//无返回值
void MyI2C_Stop(void)
{
	//确保起始时两线均为低电平
	MyI2C_0_SCL_Ctrl(0);
	//等待I2C电平变更
	MyI2C_delay();
	//确保起始时两线均为低电平
	MyI2C_0_SDA_Ctrl(0);
	//等待I2C电平变更
	MyI2C_delay();
	
	//拉高SCL
	MyI2C_0_SCL_Ctrl(1);
	//等待I2C电平变更
	MyI2C_delay();
	//拉高SDA
	MyI2C_0_SDA_Ctrl(1);
	//等待I2C电平变更
	MyI2C_delay();
}

//I2C协议，发送单个数据
//参数：data : 需要发送的数据
//无返回值
void MyI2C_SendOneData(unsigned char data)
{
	//定义缓存变量
	unsigned char temp=0;
	//循环发送8位数据
	for(unsigned char i=0;i<8;i++)
	{
		//从最高位从左往右依次取出
		temp = (data & (0x80 >> i));
		//如果是1
		if(temp)
		{
			//挂载数据1
			MyI2C_0_SDA_Ctrl(1);
			MyI2C_delay();
		}
		else
		{
			//挂载数据0
			MyI2C_0_SDA_Ctrl(0);
			MyI2C_delay();
		}
		//拉高时钟线，通知从机读取数据
		MyI2C_0_SCL_Ctrl(1);
		MyI2C_delay();
		//拉低时钟线，准备发送下一位数据
		MyI2C_0_SCL_Ctrl(0);
		MyI2C_delay();
	}
}

//I2C协议，接收一个字节数据
//无参
//返回值 接收到的一个字节数据
unsigned char MyI2C_ReceiveOneData(void)
{
	//定义缓存变量
	unsigned char temp=0;
	//释放总线
	MyI2C_0_SDA_Ctrl(1);
	//循环接收8位数据
	for(unsigned char i=0;i<8;i++)
	{
		//拉高时钟线，准备读取数据
		MyI2C_0_SCL_Ctrl(1);
		MyI2C_delay();
		//读取SDA电平状态
		if(MyI2C_0_SDA_Read())
		{
			//依次存储数据
			temp |= (0x80>>i);
		}
		//拉低时钟线，通知从机准备下一位数据
		MyI2C_0_SCL_Ctrl(0);
		MyI2C_delay();
	}
	//返回接收到的值
	return temp;
}

//I2C协议 发送应答
//参数: ACK:   0:应答 1:不应答
void MyI2C_SendACK(unsigned char ACK)
{
	//应答判断
	if(ACK)
	{
		MyI2C_0_SDA_Ctrl(1);
		MyI2C_delay();
	}
	else
	{
		MyI2C_0_SDA_Ctrl(0);
		MyI2C_delay();
	}
	//拉高SCL 告诉从机接收数据
	MyI2C_0_SCL_Ctrl(1);
	MyI2C_delay();
	//拉低SCL 准备发送下一位数据
	MyI2C_0_SCL_Ctrl(0);
	MyI2C_delay();
}

//I2C协议 接收应答
//无参
//返回值： 应答值 0：从机应答 1：从机不应答
unsigned char MyI2C_ReceiveACK(void)
{
	unsigned char temp=0;
	//释放SDA总线
	MyI2C_0_SDA_Ctrl(1);
	//拉高SCL 准备接收应答
	MyI2C_0_SCL_Ctrl(1);
	MyI2C_delay();
	//读取SDA 挂载数据
	temp = (MyI2C_0_SDA_Read() ? 1 : 0);
	//拉低SCL 准备下一阶段
	MyI2C_0_SCL_Ctrl(0);
	MyI2C_delay();
	//返回应答值
	return temp;
}




